﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Working.Aplicação;
using Working.Aplicação.Vendas.Properties;

using Working.Domínio.Vendas;
using Working.Domínio.Produtos;

namespace Working.Aplicação.Vendas
{
    public enum EstadoDaVenda { EsperandoVenda, InserindoItens, AguardandoPagamento, AguardandoFinalização };

    public class ControladorDeVendas : ControladorBase
    {

        private CatalogoDeProdutos catálogo;

        public ControladorDeVendas(CatalogoDeProdutos catálogo)
        {
            if(catálogo == null)
                throw new ArgumentException(Resources.SCatálogoDeProdutosInválido, "catálogo");

            this.catálogo = catálogo;
            this.vendaCorrente = null;
            this.estado = EstadoDaVenda.EsperandoVenda;
        }

        public Venda VendaCorrente
        {
            get { return this.vendaCorrente; }
        } private Venda vendaCorrente;

        public EstadoDaVenda Estado
        {
            get { return this.estado; }
        } private EstadoDaVenda estado;

        public void IniciarNovaVenda()
        {
            if(this.Estado != EstadoDaVenda.EsperandoVenda)
                throw new ApplicationException(Resources.SNovaVendaNãoPodeSerIniciada);

            this.vendaCorrente = new Venda();
            this.estado = EstadoDaVenda.InserindoItens;
        }

        public void AdicionarItem(string itemID)
        {
            AdicionarItem(itemID, 1);
        }

        public void AdicionarItem(string itemID, int quantidade)
        {
            //Consiste o correto estado do processo de venda
            if(this.Estado == EstadoDaVenda.EsperandoVenda)
                throw new ApplicationException(Resources.SVendaNãoIniciada);

            if(this.Estado == EstadoDaVenda.AguardandoFinalização)
                throw new ApplicationException(Resources.SNãoÉPossívelAdicionarNovosItens);

            this.estado = EstadoDaVenda.InserindoItens;
            Produto produto = this.catálogo.ObterProduto(itemID);

            if(produto != null)
                this.vendaCorrente.AdicionarItem(produto, quantidade);
            else
                throw new ApplicationException(string.Format(Resources.SProdutoNãoEncontradoEmCatálogo, 
                    itemID, this.catálogo.Identificação));

        }

        public void CompletarVenda()
        {
            if(this.Estado == EstadoDaVenda.EsperandoVenda)
                throw new ApplicationException(Resources.SVendaNãoIniciada);

            if(this.Estado == EstadoDaVenda.AguardandoFinalização)
                throw new ApplicationException(Resources.SVendaNãoIniciada);

            this.vendaCorrente.Completar();

            if(this.vendaCorrente.Saldo() < 0)
                this.estado = EstadoDaVenda.AguardandoPagamento;
            else
                this.estado = EstadoDaVenda.AguardandoFinalização;
        }

        public void FazerPagamentoEmDinheiro(decimal quantia)
        {
            if(this.Estado == EstadoDaVenda.EsperandoVenda)
                throw new ApplicationException(Resources.SVendaNãoIniciada);

            if(this.vendaCorrente.EstáFinalizada)
                throw new ApplicationException(Resources.SVendaFinalizada);

            if(this.Estado == EstadoDaVenda.InserindoItens)
                throw new ApplicationException(Resources.SPagamentoNãoPodeSerRealizado);

            this.vendaCorrente.FazerPagamento(quantia);

            //Continua aguardando pagamento caso saldo seja insuficiente
            if(this.vendaCorrente.Saldo() >= 0)
                this.estado = EstadoDaVenda.AguardandoFinalização;
        }

        public void FinalizarVenda()
        {
            if(this.Estado == EstadoDaVenda.EsperandoVenda)
                throw new ApplicationException(Resources.SVendaNãoIniciada);

            if(this.Estado != EstadoDaVenda.AguardandoFinalização)
                throw new ApplicationException(Resources.SVendaNãoPodeSerFinalizada);

            this.vendaCorrente.Finalizar();
            //Todo: Enviar dados da venda para sistemas de faturamento e estoque
            //...

            //Todo: Imprimir recibo da venda, nota fiscal ou cupom fiscal
            //...

            //Todo: Armazenar os dados da venda e enviar para sistemas de faturamento e estoque
            //...

            this.vendaCorrente = null;
            this.estado = EstadoDaVenda.EsperandoVenda;
        }
    }
}
